/**
 * 打印功能实现
 * 基于旧项目的打印逻辑进行迁移
 */

import { ElMessage } from 'element-plus'
import { isEmpty } from '@/utils/toolsValidate'
import { PrinterInfo, PrintTask, PrintResult } from './types'
import printQueueNotificationService from '@/components/PrintQueueNotification/service'

/**
 * 打印队列管理类
 */
class PrintQueue {
    private queue: PrintTask[] = []
    private isProcessing = false

    /**
     * 添加打印任务
     */
    async addTask(task: PrintTask): Promise<PrintResult> {
        return new Promise((resolve, reject) => {
            this.queue.push(task)

            // 更新队列状态通知
            this.updateQueueNotification()

            this.processQueue()

            // 监听任务完成
            const checkTask = () => {
                const completedTask = this.queue.find(t => t.id === task.id && t.status === 'completed')
                const failedTask = this.queue.find(t => t.id === task.id && t.status === 'failed')

                if (completedTask) {
                    // 更新队列状态通知
                    this.updateQueueNotification()
                    resolve({ success: true, taskId: task.id })
                } else if (failedTask) {
                    // 更新队列状态通知
                    this.updateQueueNotification()
                    reject(new Error(failedTask.error || '打印失败'))
                } else {
                    setTimeout(checkTask, 100)
                }
            }
            checkTask()
        })
    }

    /**
     * 处理打印队列
     */
    private async processQueue(): Promise<void> {
        if (this.isProcessing || this.queue.length === 0) {
            return
        }

        this.isProcessing = true

        while (this.queue.length > 0) {
            const task = this.queue.find(t => t.status === 'pending')
            if (!task) break

            task.status = 'printing'

            // 更新队列状态通知 - 开始打印
            this.updateQueueNotification()
            this.updateCurrentTaskNotification(task)

            try {
                await this.executePrint(task)
                task.status = 'completed'
                task.completedAt = new Date()

                // 显示打印完成提示
                this.showPrintCompleteNotification(task)
            } catch (error) {
                task.status = 'failed'
                task.error = error instanceof Error ? error.message : '未知错误'
                console.error('打印任务失败:', error)

                // 显示打印失败提示
                this.showPrintFailedNotification(task)
            }

            // 更新队列状态通知 - 打印完成或失败
            this.updateQueueNotification()
        }

        this.isProcessing = false
    }

    /**
     * 执行打印任务
     */
    private async executePrint(task: PrintTask): Promise<void> {
        return new Promise((resolve, reject) => {
            try {
                // 优先使用新的安全API
                // 起菜单：每个菜品单独打印小票
                if (task.pageType === 'startCookBill.html') {
                    if (!isEmpty(task.data?.detail?.foodList)) {
                        const foodList = task.data.detail.foodList
                        // 为每个菜品创建独立的打印任务 - 串行打印
                        const printItemsSequentially = async () => {
                            for (const item of foodList) {
                                // 创建打印数据的函数，避免作用域问题
                                const createPrintData = () => ({
                                    foodName: item.name,
                                    foodMoney: item.money,
                                    foodNum: item.num,
                                    foodUnit: item.unit,
                                    foodNotes: item.notes?.length ? item.notes.join('、') : '',
                                    deskList: task.data.detail.deskList,
                                    create_time: task.data.create_time,
                                    clerkName: task.data.detail.clerkName,
                                    ticket_id: task.data.ticket_id,
                                    shopName: task.data.detail.shopName,
                                    printerPage: task.pageType,
                                    printerName: task.printerName,
                                    ...task.data
                                })

                                try {
                                    // 等待每个菜品打印完成后再打印下一个
                                    await (window as any).system.printStart(task.printerName, createPrintData(), task.pageType)
                                    console.log('打印完成:', item.name)
                                } catch (error) {
                                    console.error('打印失败:', error, item.name)
                                    ElMessage.error(`打印失败: ${item.name} - ${error.message || '未知错误'}`)
                                    // 可以选择继续打印下一个或停止整个任务
                                }
                            }
                        }

                        // 执行串行打印
                        printItemsSequentially().finally(() => {
                            resolve()
                        })
                    }
                } else {
                    // 其他类型的打印任务直接调用
                    (window as any).system.printStart(task.printerName, task.data, task.pageType)
                        .then(res => {
                            console.log('打印完成:', res)
                            resolve()
                        })
                        .catch(error => {
                            console.error('打印失败:', error)
                            ElMessage.error('打印失败: ' + (error.message || '未知错误'))
                            reject(error)
                        })
                }

            } catch (error) {
                console.error('打印任务失败:', error)
                ElMessage.error('打印任务失败')
                reject(error)
            }
        })
    }

    /**
     * 获取队列状态
     */
    getQueueStatus() {
        return {
            total: this.queue.length,
            pending: this.queue.filter(t => t.status === 'pending').length,
            printing: this.queue.filter(t => t.status === 'printing').length,
            completed: this.queue.filter(t => t.status === 'completed').length,
            failed: this.queue.filter(t => t.status === 'failed').length
        }
    }

    /**
     * 清空队列
     */
    clearQueue() {
        this.queue = []
        // 更新队列状态通知
        this.updateQueueNotification()
    }

    /**
     * 更新队列状态通知
     */
    private updateQueueNotification() {
        const status = this.getQueueStatus()
        printQueueNotificationService.updateQueueStatus(status)
    }

    /**
     * 更新当前任务通知
     */
    private updateCurrentTaskNotification(task: PrintTask) {
        const taskName = this.getTaskDisplayName(task)
        printQueueNotificationService.showPrintStart(taskName)
    }

    /**
     * 显示打印完成通知
     */
    private showPrintCompleteNotification(task: PrintTask) {
        const taskName = this.getTaskDisplayName(task)
        printQueueNotificationService.showPrintComplete(taskName)
    }

    /**
     * 显示打印失败通知
     */
    private showPrintFailedNotification(task: PrintTask) {
        const taskName = this.getTaskDisplayName(task)
        printQueueNotificationService.showPrintFailed(taskName)
    }

    /**
     * 获取任务显示名称
     */
    private getTaskDisplayName(task: PrintTask): string {
        // 根据打印类型和数据结构获取合适的显示名称
        if (task.pageType === 'startCookBill.html') {
            // 起菜单 - 显示菜品名称
            const foodList = task.data?.detail?.foodList
            if (foodList && foodList.length > 0) {
                if (foodList.length === 1) {
                    return foodList[0].name || '起菜单'
                } else {
                    return `起菜单(${foodList.length}个菜品)`
                }
            }
            return '起菜单'
        } else if (task.pageType === 'orderDishBill.html') {
            return '点菜单'
        } else if (task.pageType === 'waitCookingCard.html') {
            return '等叫单'
        } else if (task.pageType === 'urgeCookingCard.html') {
            return '催菜单'
        } else if (task.pageType === 'FoodRefundBill.html') {
            return '退菜单'
        } else if (task.pageType === 'preconsolidationBill.html') {
            return '预结单'
        } else if (task.pageType === 'statementBill.html') {
            return '结账单'
        } else if (task.pageType === 'shiftHandover.html') {
            return '交班单'
        } else {
            // 其他类型，尝试从数据中获取名称
            return task.data?.ticket_id ? `订单${task.data.ticket_id}` : '打印任务'
        }
    }
}

// 全局打印队列实例
const printQueue = new PrintQueue()

/**
 * 获取打印机列表
 */
export async function getPrinterList(): Promise<PrinterInfo[]> {
    try {
        const printers = await (window as any).system.getPrinters()
        console.log('printers:', printers)
        return printers
    } catch (error) {
        console.error('获取打印机列表失败:', error)
        return []
    }
}

/**
 * 获取打印机状态
 */
export async function getPrinterStatus(printerName: string): Promise<boolean> {
    try {
        const printers = await getPrinterList()
        const printer = printers.find(p => p.name === printerName)
        return printer?.status === 'online' || false
    } catch (error) {
        console.error('获取打印机状态失败:', error)
        return false
    }
}

/**
 * 打印订单
 * @param printerName 打印机名称
 * @param order 订单数据
 * @param printerPage 打印页面类型
 */
export async function printOrder(printerName: string, order: any, printerPage: string): Promise<PrintResult> {
    try {
        console.log('开始打印订单:', { printerName, order, printerPage })
        // 创建打印任务
        const task: PrintTask = {
            id: `print_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
            printerName,
            data: order,
            pageType: printerPage,
            status: 'pending',
            createdAt: new Date()
        }

        // 添加到打印队列
        return await printQueue.addTask(task)

    } catch (error) {
        console.error('打印订单失败:', error)
        throw error
    }
}

/**
 * 执行打印队列
 */
export async function executePrintQueue(): Promise<void> {
    // 这个方法主要用于手动触发队列处理
    // 队列会自动处理，但有时需要手动触发
    console.log('手动执行打印队列')
}

/**
 * 调用打印功能
 */
export async function invokePrint(printerName: string, data: any, pageType: string): Promise<PrintResult> {
    return printOrder(printerName, data, pageType)
}

/**
 * 浏览器打印（备用方案）
 */
export function browserPrint(data: any): void {
    console.log('浏览器打印功能:', data)
    // 在浏览器环境下，可以打开打印对话框
    window.print()
}


/**
 * 获取打印队列状态
 */
export function getPrintQueueStatus() {
    return printQueue.getQueueStatus()
}

/**
 * 清空打印队列
 */
export function clearPrintQueue() {
    printQueue.clearQueue()
}

/**
 * 处理WebSocket打印消息
 * @param messageData 打印消息数据
 */
export async function handlePrintMessage(messageData: any): Promise<void> {
    try {
        const ticketId = messageData?.ticket_id || 'unknown'
        console.log('打印模块处理消息 - 票据ID:', ticketId, '消息:', messageData)

        // 获取打印机列表
        const printerList = await getPrinterList()
        const printerNames = printerList.map((item: any) => item.name) || []

        const printerName = messageData?.printer?.real_name || null
        if (!printerName || !printerNames.includes(printerName)) {
            console.warn('打印机不存在:', printerName)
            return
        }

        // 打印页面映射 - 直接使用现有HTML模板
        const PRINTER_PAGE_MAP: Record<string, string> = {
            'QC': 'startCookBill.html',        // 起菜单
            'DC': 'orderDishBill.html',        // 点菜单
            'DJ': 'waitCookingCard.html',      // 等叫单
            'CC': 'urgeCookingCard.html',      // 催菜单
            'TC': 'FoodRefundBill.html',       // 退菜单
            'BG': 'FoodCountCard.html',        // 数量变更单
            'YJ': 'preconsolidationBill.html', // 预结单
            'JZ': 'statementBill.html',        // 结账单
            'HC': 'RemoveFoodCard.html',       // 划菜总单[全单重打]
            'CD': 'FoodReturnCard.html',       // 重打菜品单【单菜重打】
            'ZT': 'TransformNoticeCard.html',  // 转台通知单
            'CZT': 'FoodTurntableNotificationCard.html', // 菜品转台通知单
            'YD': 'bookBill.html',             // 预订单
            'JB': 'shiftHandover.html',        // 交班单
            'FS': 'timeDivisionSale.html',     // 分时销售
            'MR': 'dailySaleSummary.html',     // 销售报表
            'CF': 'foodCategorySummary.html',  // 菜品分类报表
            'CZ': 'rechargeBill.html',         // 充值单
            'HK': 'backBill.html',             // 回款单
            'YF': 'depositInvoiceBill.html',   // 定金发票单
            'CW': 'StorageManagement.html'     // 存物单
        }

        // 根据消息类型获取对应的打印页面
        const printerPage = PRINTER_PAGE_MAP[messageData.type]
        if (!printerPage) {
            console.warn('未知的打印类型:', messageData.type)
            return
        }

        // 调用打印功能
        await printOrder(printerName, messageData, printerPage)
        console.log('打印任务已提交')

    } catch (error) {
        console.error('打印模块处理消息失败:', error)
        throw error
    }
}
